/* Title: -> c.event
 * Purpose: system-independent central processing for window sytem events.
 *
 */

#define BOOL int
#define TRUE 1
#define FALSE 0

#include <stdlib.h>

#include "trace.h"
#include "os.h"
#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "menu.h"
#include "alarm.h"    

#include "event.h"


/* --------- masking of events ---------- */

static wimp_emask event__mask = wimp_EMNULL;

void event_setmask (wimp_emask mask)
{
  event__mask = mask;
}


wimp_emask event_getmask (void)
{
  return (event__mask);
}


/* -------- attaching menus. -------- */

/* An event_w is in fact a wimp_w. */

typedef struct {
  menu m;
  event_menu_maker maker;
  event_menu_proc event;
  void *handle;
} mstr;

BOOL event__attach(event_w w,
  menu m, event_menu_maker menumaker, event_menu_proc eventproc, void *handle)
{
  mstr *p = win_getmenuh(w);
  if (m == 0 && menumaker == 0) { /* cancelling */
    if (p != 0) { /* something to cancel */
      free(p);
      win_setmenuh(w, 0);
    };
  } else {
    if (p == 0) p = malloc(sizeof(mstr));
    if (p == 0) return FALSE;
    p->m = m;
    p->maker = menumaker;
    p->event = eventproc;
    p->handle = handle;
    win_setmenuh(w, p);
  };
  return TRUE;
}

BOOL event_attachmenu(event_w w,
  menu m, event_menu_proc eventproc, void* handle)
{
  return event__attach(w, m, 0, eventproc, handle);
}

BOOL event_attachmenumaker(event_w w,
  event_menu_maker menumaker, event_menu_proc eventproc, void *handle)
{
  return event__attach(w, 0, menumaker, eventproc, handle);
}

/* -------- Processing Events. -------- */

static wimp_w event__current_menu_window = 0;
  /* 0 if no menu currently visible */
static menu event__current_menu;
static BOOL event__current_destroy_after; /* set if we made the menu */
static int event__menux = 0;
static int event__menuy = 0;
static BOOL event__last_was_menu_hit = FALSE;
static BOOL event__recreation ;

BOOL event__process(wimp_eventstr *e)
{
static int xx;
  /* Look for submenu requests, and if found turn them into menu hits. */
  /* People wishing to respond can pick up the original from wimpt. */
  if (e->e == wimp_ESEND && e->data.msg.hdr.action == wimp_MMENUWARN) {
    int i;
    e->e = wimp_EMENU;
    i = 0;
    while ((e->data.menu[i] = e->data.msg.data.words[i+3]) != -1) i++;
    e->data.menu[i++] = 0;
    e->data.menu[i++] = -1;
  };

  /* Look for menu events */
  if (e->e == wimp_EBUT && (wimp_BMID & e->data.but.m.bbits) != 0) {
    /* set up a menu! */
    mstr *p;
    if (e->data.but.m.w <= -1) e->data.but.m.w = win_ICONBAR;
    p = win_getmenuh(e->data.but.m.w);
    if (p != 0) {
      wimp_menuhdr *m;
      event__current_menu_window = e->data.but.m.w;
      event__current_menu = p->m;
      event__current_destroy_after = FALSE;
      if (p->m != 0) {
        m = (wimp_menuhdr*) menu_syshandle(p->m);
      } else if (p->maker != 0) {
        event__current_destroy_after = FALSE;
          /* WRS: menu destruction taken out*/
        event__recreation = 0 ;
        event__current_menu = p->maker(p->handle);
        m = (wimp_menuhdr*) menu_syshandle(event__current_menu);
      } else {
        m = 0;
      };
      if (event__current_menu_window == win_ICONBAR) {
        /* move icon bar menus up a bit. */
        e->data.but.m.x -= 16 /* m->width/2 */;
        e->data.but.m.y = 96;
        {
          wimp_menuitem *mi = (wimp_menuitem*) (m + 1);
          while (1) {
            e->data.but.m.y += m->height + m->gap;
            if ((mi->flags & wimp_MLAST) != 0) break;
            mi++;
          };
        };
      };
      event__menux = e->data.but.m.x;
      event__menuy = e->data.but.m.y;
      wimpt_complain(wimp_create_menu((wimp_menustr*) m, e->data.but.m.x - 48, e->data.but.m.y));
      return FALSE;
    };
  } else if (e->e == wimp_EMENU && event__current_menu != 0) {
    mstr *p;
    p = win_getmenuh(event__current_menu_window);
    if (p == 0) {
      /* if the menu registration has been cancelled,
      we hand the event on. */
    } else {
      int i;
      char a[20];
      for (i = 0; e->data.menu[i] != -1; i++) {a[i] = 1 + e->data.menu[i];};
      a[i] = 0;
      p->event(p->handle, a);
      event__last_was_menu_hit = TRUE; /* menu has still to be deleted. */
      return FALSE;
    };
  };

  if (e->e == wimp_ENULL)
  {
    int dummy_time;
    BOOL pending_alarm = alarm_next(&dummy_time);
    tracef0("Got a null\n");
    if (pending_alarm != 0 && dummy_time <= alarm_timenow())
    {
      tracef1("Calling alarm at %d\n", alarm_timenow());
      alarm_callnext();
    }
  }
  
  /* now process the event */
if(e->e == 0)
{
   xx=1;
}
  if (win_processevent(e)) {
    /* all is well, it was claimed */
  } else if (e->e == wimp_ENULL) {
    /* machine idle: say so */
    return TRUE;
  } else if (e->e == wimp_EOPEN) {
    /* Assume it's a menu being moved */
    wimpt_complain(wimp_open_wind(&e->data.o));
  } else {
  };
  return FALSE;
}

void event__poll(wimp_emask mask, wimp_eventstr *result)
{
  if (event__last_was_menu_hit && wimpt_last_event()->e == wimp_EMENU) {
    wimp_mousestr m;
    event__last_was_menu_hit = FALSE;
    wimpt_noerr(wimp_get_point_info(&m));
    if (0 != (wimp_BRIGHT & m.bbits)) {
      /* An ADJ-hit. The menu should be recreated. */
      mstr *p = win_getmenuh(event__current_menu_window);
      if (p != 0) {
        wimp_menustr *m;
        event__current_menu = p->m;
        event__current_destroy_after = FALSE;
        if (p->m != 0) {
          m = (wimp_menustr*) menu_syshandle(p->m);
        } else if (p->maker != 0) {
          event__recreation = 1 ;
          event__current_menu = p->maker(p->handle);
          m = (wimp_menustr*) menu_syshandle(event__current_menu);
        } else {
          m = 0;
        };
        wimpt_complain(wimp_create_menu(m, event__menux, event__menuy));
      };
    };
  };
  tracef0("doing poll.\n");
  wimpt_complain(wimpt_poll(mask, result));
  tracef0("poll done.\n");
}

void event_process(void)
{
  tracef0("event_process.\n");
  if (win_activeno() == 0) exit(0); /* stop program */ 
  {
    wimp_eventstr e;
    event__poll(event_getmask(), &e);
    (void) event__process(&e);
  };
}

BOOL event_anywindows()
{
  return(win_activeno() != 0);
}


BOOL event_is_menu_being_recreated(void)
{
 return event__recreation ;
}


void event_clear_current_menu(void)
/*********************************/
/* Altered by JSD */
{
   event__current_menu_window = 0;   /* ADDED */
   event__current_menu = 0;   /* ADDED */
   wimpt_noerr(wimp_create_menu((wimp_menustr*) -1, 0, 0));
}

/* end */
